package ochart.core
{
	import flash.utils.Dictionary;
	
	import ochart.chartClasses.IChartObject;
	import ochart.elements.areas.Area;
	import ochart.elements.axes.RightYAxis;
	import ochart.elements.axes.Tick;
	import ochart.elements.axes.XAxis;
	import ochart.elements.axes.YAxis;
	import ochart.elements.background.Background;
	import ochart.elements.bars.Bar;
	import ochart.elements.dots.Dot;
	import ochart.elements.labels.DataTip;
	import ochart.elements.labels.Label;
	import ochart.elements.labels.Title;
	import ochart.elements.lines.Line;
	import ochart.elements.lines.LineBase;
	import ochart.elements.pies.Pie;
	import ochart.elements.radars.Radar;
	import ochart.utils.ArrayUtil;
	import ochart.utils.logging.Logger;

	public class UpdateList
	{
		public static const CLASS_NAME:String = "UpdateList"
		
		public function get className():String
		{
			return CLASS_NAME;
		}
		
		public static const ALIAS:String = "updateList";
		
		public function get alias():String
		{
			return ALIAS;
		}
		
		private static var logger:Logger = Logger.getLogger(CLASS_NAME);
		
		private static var _instance:UpdateList = null;
		
		public static function get instance():UpdateList
		{
			if(!_instance)
			{
				_instance = new UpdateList();
			}
			return _instance;
		}
		
		private var dictionary:Dictionary = null;
		
		public function UpdateList()
		{
			dictionary = new Dictionary();
		}
		
		public function add(object:IChartObject):void
		{
			if(!object)
			{
				return;
			}
			var array:Array = dictionary[object.className];
			if(!array)
			{
				array = [];
				dictionary[object.className] = array;
			}
			if(!ArrayUtil.containsValue(array, object))
			{
				array.push(object);
			}
		}
		
		public function remove(object:IChartObject):void
		{
			if(!object)
			{
				return;
			}
			var array:Array = dictionary[object.className];
			if(!array)
			{
				return;
			}
			if(ArrayUtil.containsValue(array, object))
			{
				ArrayUtil.removeValue(array, object);
			}
		}
		
		public const rangeArray:Array = [
			Background.CLASS_NAME,
			Title.CLASS_NAME,
			Tick.CLASS_NAME,
			Label.CLASS_NAME,
			
			XAxis.CLASS_NAME,
			YAxis.CLASS_NAME,
			RightYAxis.CLASS_NAME,
			
			Area.CLASS_NAME,
			Bar.CLASS_NAME,
			Dot.CLASS_NAME,
			Line.CLASS_NAME,
			Pie.CLASS_NAME,
			Radar.CLASS_NAME,
			
			XYChart.CLASS_NAME,
			PieChart.CLASS_NAME,
			
			DataTip.CLASS_NAME
		];
		
		public function update():void
		{
			var startTime:Number = new Date().getTime();
			var end:Boolean = false;
			var count:Number = 0;
			for each(var className:String in rangeArray)
			{
				var array:Array = dictionary[className];
				if(!array)
				{
					continue;
				}
				count += array.length;
				while(array.length > 0)
				{
					var object:IChartObject = array[0];
					object.update();
					if(isExistHigherPriority(className))
					{
						logger.info("有优先级比["+ className +"]更高的元素需要更新,返回重新开始更新");
						end = true;
					}
				}
				if(end)
				{
					break;
				}
			}
			var endTime:Number = new Date().getTime();
			if(count > 0)
			{
				logger.debug("更新[" + count + "]个元素,耗时[" + (endTime - startTime) + "]毫秒");
			}
		}
		
		private function isExistHigherPriority(value:String):Boolean
		{
			for each(var className:String in rangeArray)
			{
				if(className == value)
				{
					break;
				}
				var array:Array = dictionary[className];
				if(!array)
				{
					continue;
				}
				if(array.length > 0)
				{
					return true;
				}
			}
			return false;
		}
	}
}